package com.dingding.special.order.publish.dao.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.dingding.common.core.base.daox.ICriteriaBaseDao;
import com.dingding.common.core.base.daox.ISQLBaseDao;
import com.dingding.common.core.beans.Channelreltourroute;
import com.dingding.common.core.beans.Tourroute;
import com.dingding.common.core.beans.special.UserspecialorderT;
import com.dingding.common.core.util.GetDistanceUtil;
import com.dingding.common.core.util.ToolUtil;
import com.dingding.common.core.util.dto.CalculatDistanceDTO;
import com.dingding.facade.special.trasfer.place.ReqBackstagePlace;
import com.dingding.facade.special.trasfer.route.RouteDto;
import com.dingding.special.common.exception.bussiness.BizExpEnum;
import com.dingding.special.common.exception.bussiness.BussinessException;
import com.dingding.special.common.exception.server.ServerException;
import com.dingding.special.common.exception.server.ServerExpEnum;
import com.dingding.special.order.publish.dao.IPublishSpecialOrderDao;

/**
 * @Description:发布专车单
 * @author fengshuonan
 * @date 2016年9月13日 下午3:39:01
 * @version 叮叮搭车
 * @since 2.4
 */
@Component("publishSpecialOrderDao")
public class PublishSpecialOrderDaoImpl implements IPublishSpecialOrderDao{

	@Resource(name = "criteriaBaseDao")
	private ICriteriaBaseDao criteriaBaseDao;
	
	@Resource(name = "SQLBaseDao")
	private ISQLBaseDao sqlBaseDao;
	
	private Logger log = Logger.getLogger(this.getClass());
	
	@Override
	@Transactional(readOnly = true)
	public Boolean haveMatchingOrder(String userId,int setOutType) {
		Criterion criterion = Restrictions.eq("placeOrderUserId", userId);
		try {
			List<UserspecialorderT> list = this.criteriaBaseDao.queryCriteriaList(
					UserspecialorderT.class, criterion);
			if(list == null || list.size() <= 0){
				return false;
			}else{
				//如果订单列表中有匹配的setOutType一致的，就说明有进行中订单
				for(UserspecialorderT userspecialorderT : list){
					if(userspecialorderT.getSetOutType() == setOutType){
						return true;
					}
				}
				//遍历一遍没有和参数setOutType一致的，说明没有该类型的进心中订单
				return false;
			}
		} catch (HibernateException e) {
			log.error("检查是否有进行中订单时出错：用户id" + userId + ".PublishSpecialOrderDaoImpl : haveMatchingOrder()",e);
			throw new ServerException(ServerExpEnum.SERVER_DATABASE_EXCEPTION);
		}
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public boolean saveToDb(UserspecialorderT userspecialorderT) {
		try {
			return this.criteriaBaseDao.save(userspecialorderT);
		} catch (HibernateException e) {
			log.error("添加UserspecialorderT到数据库失败！PublishSpecialOrderDaoImpl : haveMatchingOrder()",e);
			throw new ServerException(ServerExpEnum.SERVER_DATABASE_EXCEPTION);
		}
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public UserspecialorderT generateUserSpecialOrder(String userId, ReqBackstagePlace reqBackstagePlace) {
		UserspecialorderT userspecialorderT = new UserspecialorderT();
		
		/**
		 * 生成订单的基本信息
		 */
		userspecialorderT.setSpecialOrderId(ToolUtil.getUid());
		userspecialorderT.setPlaceOrderUserId(userId);
		userspecialorderT.setCreateTime(new Date());
		userspecialorderT.setPublishType(4);
		userspecialorderT.setOrderStatus(1);//1:待指派  2:待上车(已指派)  3:已上车  4:待支付(已到达)  5:已完成  6:已取消
		userspecialorderT.setEstimateDistance(new BigDecimal(0));
		userspecialorderT.setEstimateDuration(new BigDecimal(0));
		
		if(reqBackstagePlace.getRealSelect() == 1){
			userspecialorderT.setSetOutTime(userspecialorderT.getCreateTime());
		}else{
			userspecialorderT.setSetOutTime(reqBackstagePlace.getOrderTime());
		}
		
		/**
		 * 生成出发时间
		 */
		if(reqBackstagePlace.getRealSelect() == 1){
			userspecialorderT.setSetOutTime(new Date());
		}else{
			userspecialorderT.setSetOutTime(reqBackstagePlace.getOrderTime());
		}
		
		/**
		 * 先把请求中带的信息填充到临时订单中
		 */
		userspecialorderT = reqBackstagePlace.toUserSpecialOrderT(userspecialorderT);
		
		/**
		 * 查出旅游路线对应的地方的名称和经纬度
		 */
		String chooseType = reqBackstagePlace.getChoosedType().toLowerCase(); //客户端手动填写地址的类型是start或者end
		String routeId = null;									//旅游路线id
		if("start".equals(chooseType)){							//客户端手动填写的是出发地，那么目的地就是选择的
			routeId = reqBackstagePlace.getEndAddrSelectInput();
		}else{
			routeId = reqBackstagePlace.getStartAddrSelectInput();
		}
		userspecialorderT.setRouteId(routeId);
		Tourroute tourroute = null;
		try {
			tourroute = this.criteriaBaseDao.queryCriteriaListUnique(Tourroute.class,Restrictions.eq("trId", routeId));
		} catch (HibernateException e) {
			log.error("获取旅游路线详情出现错误！PublishSpecialOrderDaoImpl ：generateUserSpecialOrder()",e);
			throw new ServerException(ServerExpEnum.SERVER_DATABASE_EXCEPTION);
		}
		if("start".equals(chooseType)){			//客户端手动填写的是出发地，那么目的地就是选择的
			userspecialorderT.setEndAddress(tourroute.getRouteName());
			userspecialorderT.setEndLatitude(tourroute.getLatitude());
			userspecialorderT.setEndLongitude(tourroute.getLongitude());
		}else{
			userspecialorderT.setStartAddress(tourroute.getRouteName());
			userspecialorderT.setStartLatitude(tourroute.getLatitude());
			userspecialorderT.setStartLongitude(tourroute.getLongitude());
		}
		
		/**
		 * 查询到该旅游路线的一口价
		 */
		try {
			Channelreltourroute channelreltourroute = this.criteriaBaseDao.queryCriteriaListUnique(
					Channelreltourroute.class, 
					Restrictions.and(
							Restrictions.eq("depId", reqBackstagePlace.getDepartmentKey()),
							Restrictions.eq("routeId", routeId)));
			if(channelreltourroute == null){//查询不到该旅游公司
				throw new BussinessException(BizExpEnum.NOT_FOUND_TRAVEL_AGC);
			}
			if(channelreltourroute.getCrtrStatus() != 1){//旅游公司作废
				throw new BussinessException(BizExpEnum.TRAVLE_AGC_NOUSE);
			}else{
				if(channelreltourroute.getNumber() <= 0){//旅游公司费用不够
					throw new BussinessException(BizExpEnum.TRAVLE_AGC_FEE_NOT_ENOUGH);
				}else{
					userspecialorderT.setTotalMoney(new BigDecimal(channelreltourroute.getPrice()));
					userspecialorderT.setEstimateMoney(new BigDecimal(channelreltourroute.getPrice()));
				}
			}
		} catch (HibernateException e) {
			log.error("查询旅游公司的一口价的时候数据库错误！PublishSpecialOrderDaoImpl:generateUserSpecialOrder()",e);
			throw new ServerException(ServerExpEnum.SERVER_DATABASE_EXCEPTION);
		}
		
		/**
		 * 设置下单城市，预估距离，预估时间
		 * TODO 定位可能不准，需要修改
		 */
		CalculatDistanceDTO calculatDistanceDTO = GetDistanceUtil.getSingleDistance(userspecialorderT.getStartLongitude(),
				userspecialorderT.getStartLatitude(), userspecialorderT.getEndLongitude(),
				userspecialorderT.getEndLatitude());
		userspecialorderT.setDistance(calculatDistanceDTO.getDistance());
		userspecialorderT.setEstimateDistance(calculatDistanceDTO.getDistance());
		userspecialorderT.setPlaceOrderCity(calculatDistanceDTO.getCityName());
		userspecialorderT.setPlaceOrderCityCode(calculatDistanceDTO.getCityNo());
		userspecialorderT.setEstimateDuration(calculatDistanceDTO.getEstimateDuration());
		
		return userspecialorderT;
	}

	@Override
	@Transactional(readOnly = true)
	public List<RouteDto> getRoutes(String depId) {
		try {
			List<RouteDto> list = this.sqlBaseDao.listSqlToCustomBean(RouteDto.class,
					"SELECT tr.routeName AS placeName,crt.price placeMoney,tr.trId AS placeVal FROM tourroute AS tr " +
					"INNER JOIN channelreltourroute crt ON tr.trId = crt.routeId " +
					"WHERE tr.trStatus = 1 AND crt.crtrStatus = 1 AND crt.depId = ?",depId);
			if(list != null && list.size() > 0){
				return list;
			}else{
				return null;
			}
		} catch (HibernateException e) {
			log.error("查询路线出错！PublishSpecialOrderDaoImpl : getRoutes()",e);
			return null;
		}
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public boolean downOneUseNum(String depId,String routeId) {
		
		try {
			Channelreltourroute channelreltourroute = this.criteriaBaseDao.queryCriteriaListUnique(
					Channelreltourroute.class, Restrictions.and(
							Restrictions.eq("depId", depId),Restrictions.eq("routeId", routeId)));
			if(channelreltourroute == null){
				throw new BussinessException(BizExpEnum.TABLE_ITEM_IS_NULL);
			}
			int number = channelreltourroute.getNumber();
			if(number <= 0){
				throw new BussinessException(BizExpEnum.TRAVLE_AGC_FEE_NOT_ENOUGH);//权益次数不够
			}else{
				channelreltourroute.setNumber(number-1);
				return true;
			}
		} catch (HibernateException e) {
			log.error("改变某个部门的权益次数出现错误！部门id：" + depId + "PublishSpecialOrderDaoImpl:downOneUseNum",e);
			throw new ServerException(ServerExpEnum.SERVER_DATABASE_EXCEPTION);
		}
	}

}
